package com.job51.hro.exlog.aspect;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.HttpMethod;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.job51.hro.exlog.box.WebPostJsonFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 〈一句话功能简述〉<br>
 * 〈〉
 *
 * @author pengfei.ma
 * @create 2022/5/27
 * @since 1.0.0
 */
public class BaseAspect {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static final Logger logger = LoggerFactory.getLogger(BaseAspect.class);

    public static final String REQID = "reqId";

    public static final String URI = "uri";

    public static final String METHOD = "method";

    public static final String HEADERS = "headers";

    public static final String PARAMS = "params";

    public static final String GLOBAL_REQ_ID = "globalReqId";

    public static final String APP_NAME = "appName";

    public static final String PERSONAL_MENTION = "personalMention";

    public static final String MapperFunction = "function";

    public Map<String, Object> getRequest() {
        return getRequestParams();
    }


    //获取请求的相关信息
    private Map<String, Object> getRequestParams() {
        Map<String, Object> requestParams = new HashMap<>();
        RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
        //获取请求信息
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return null;
        }
        HttpServletRequest request = attributes.getRequest();
        requestParams.put("uri", request.getRequestURI());
        // 获取请求头信息,需要注意的是，请求头中的key都会转成小写
        Enumeration<String> enumeration = request.getHeaderNames();
        JSONObject headers = new JSONObject();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            String value = request.getHeader(name);
            headers.put(name, value);
        }
        requestParams.put("headers", headers);
        //获取请求的方法
        String method = request.getMethod();
        requestParams.put("method", method);
        String params = "";
        int contentLength = request.getContentLength();
        if (HttpMethod.POST.equals(method) && contentLength > 0) {
            if (request.getParameterMap() != null && !request.getParameterMap().isEmpty()) {
                try {
                    params = objectMapper.writeValueAsString(request.getParameterMap());
                } catch (JsonProcessingException e) {
                    logger.error("json序列化异常", e);
                }
            } else {
                try {
                    InputStream inputStream = request.getInputStream();
                    if (inputStream instanceof WebPostJsonFilter.PushbackServletInputStream) {
                        byte[] buffer = new byte[contentLength];
                        for (int i = 0; i < contentLength; ) {
                            int readLen = inputStream.read(buffer, i, contentLength - i);
                            if (readLen == -1) {
                                break;
                            }
                            i += readLen;
                        }
                        ((WebPostJsonFilter.PushbackServletInputStream) inputStream).unread(buffer);
                        params = new String(buffer, StandardCharsets.UTF_8);
                    }
                } catch (Exception e) {
                    logger.error("读取请求体信息出错:", e);
                }
            }
        }
        requestParams.put("params", params);
        return requestParams;
    }
}
